import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.ArrayList;


public class UDPFileServer extends FileServer {

	private int bufferSize; // in bytes
	private int bufferFileSize; // in bytes
	private DatagramSocket ds;
	private InetAddress IPAddress;
	
	public UDPFileServer(int port) throws SocketException {
		super(port);
		this.ds = new DatagramSocket(port);
		this.bufferSize = 20480; //20Kb
		this.bufferFileSize = 8192; //8Kb
	}

	@Override
	public void serve() {
		try{
			byte[] buffer = new byte[bufferFileSize];
			
			int currentPort = 0;
			String sentence = "";
			String message = "";
			boolean isPost = false;
			byte[] bufferReve = new byte[this.bufferSize];
			DatagramPacket receivePacket = null;
			
			String fileName = "";
			int part = 0;
			int count = 0;
			File f = null;
			FileInputStream inf = null;
			
			while(true)
		      {
				 try {
					 
					 //Nhan goi tin
					 bufferReve = new byte[this.bufferSize];
					 receivePacket = new DatagramPacket(bufferReve, bufferReve.length);
					 ds.receive(receivePacket);
					 IPAddress = receivePacket.getAddress();
					 currentPort = receivePacket.getPort();
					 sentence = new String(receivePacket.getData()).trim();
					 //System.out.println("RECEIVED: " + sentence);
					 message = "NULL";
					 
					 //su ly thong diep
					 if(sentence.equalsIgnoreCase("list")){
							ArrayList<String> list = getFileList();
							if(list == null || list.size() == 0)
								message = "201";
							else{
								message = "200";
								for(String i:list){
									message += " " + i + ";";
								}
							}
							send(message.getBytes(), currentPort);
							continue;
						}
					 
					 if(sentence.length() >= 4 && sentence.substring(0, 4).equalsIgnoreCase("get ")){
							fileName = sentence.substring(4).trim();
							f = getAFileContent(fileName);
							
							if(f == null){
								message = "101";
							}
							else{
								message = "100";
								isPost = true;
								part = 0;
								inf = new FileInputStream(f);
								
							}
							send(message.getBytes(), currentPort);
							continue;
						}
					 
					 if(isPost && sentence.equalsIgnoreCase("get")){
							count = -1;
							if(inf!=null){
								buffer = new byte[bufferFileSize];
								count = inf.read(buffer, 0, bufferFileSize);
							}
							if(count <= -1){
								isPost = false;
								message = "199";
								send(message.getBytes(), currentPort);
								inf.close();
								continue;
							}
							
							String base64 = FileUtility.BytesToBase64(buffer, count);
							
							message = "<file>" + fileName + "</file><part>" + part + "</part><length>" + count + "</length><data>" + base64 + "</data>";
							send(message.getBytes(), currentPort);
							part ++;
							Thread.sleep(100);
							continue;
						}
					 //Phan hoi lai client
					 send(message.getBytes(), receivePacket.getPort());
					 
				} catch (Exception e) {
					System.err.println(e.getMessage());
				}
		         
		      }
			}catch(Exception e){
				System.err.println(e.getMessage());
			}
		
	}
	
	public void send(byte[] content, int clientPort) {
		try {
			DatagramPacket sendPacket = new DatagramPacket(content, content.length, IPAddress, clientPort);
			ds.send(sendPacket);
		} catch (IOException e) {}
	}

	public byte[] receive() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void showInfo() {
		System.out.println("UDP File Server");
		System.out.println("Port: " + getPort());
	}
}
